vec4 trilinearFilter(sampler3D volume, in VOLUME_STRUCT volumeStruct, in vec3 sampleOrg) {
	vec3 t = sampleOrg * volumeStruct.datasetDimensions_;
	vec3 f = floor(t);
	vec3 c = ceil(t);
	vec3 dft = t - f;
	vec3 dct = c - t;
	// get surrounding voxels of t
	vec3 v[8];
	v[0] = f;
	v[1] = vec3(c.x, f.yz);
	v[2] = vec3(f.x, c.y, f.z);
	v[3] = vec3(c.xy, f.z);
	v[4] = vec3(f.xy, c.z);
	v[5] = vec3(c.x, f.y, c.z);
	v[6] = vec3(f.x, c.yz);
	v[7] = c;
	for (int i = 0; i < 8; i++) {
		v[i] /= volumeStruct.datasetDimensions_;
	}


	// linear interpolation between 
	//v[0] and v[1]
	vec4 l01 = dct.x * getVoxel(volume, volumeStruct, v[0]) + dft.x * getVoxel(volume, volumeStruct, v[1]);
	// v[2] and v[3]
	vec4 l23 = dct.x * getVoxel(volume, volumeStruct, v[2]) + dft.x * getVoxel(volume, volumeStruct, v[3]);
	// v[4] and v[5]
	vec4 l45 = dct.x * getVoxel(volume, volumeStruct, v[4]) + dft.x * getVoxel(volume, volumeStruct, v[5]);
	// v[6] and v[7]
	vec4 l67 = dct.x * getVoxel(volume, volumeStruct, v[6]) + dft.x * getVoxel(volume, volumeStruct, v[7]);

	// bilinear interpolation between 
	//v[0], v[1], v[2] and v[3]
	vec4 b0123 = dct.y * l01 + dft.y * l23;
	//v[4], v[5], v[6] and v[7]
	vec4 b4567 = dct.y * l45 + dft.y * l67;

	// trilinear interpolation
	vec4 t01234567 = dct.z * b0123 + dft.z * b4567;

	return t01234567;
}